const {
  Service
} = require('uni-cloud-router')

module.exports = class ExamService extends Service {
  constructor(ctx) {
    super(ctx)
    this.questionCt = this.db.collection('question')
    this.paperCt = this.db.collection('paper')
    this.examCt = this.db.collection('exam')
    this.dbCmd = this.db.command
  }

  // 获取用户信息
  async getUserInfo(uniIdToken) {
    await this.service.user.checkToken(uniIdToken)
    const userAuth = this.ctx.auth
    console.log("userAuth", userAuth)
    return userAuth
  }

  async getExamPapers(uniIdToken) {
    // 查询到正在考试的试卷
    let inExamRes = await this.getInExamPaper()
    if (inExamRes.data.length <= 0)
      return inExamRes
    let paperList = inExamRes.data
    // 查询用户信息
    let userAuth = await this.getUserInfo(uniIdToken)
    // 查询符合用户的试卷
    let uInExamRes = await this.filterUserInExamPapers(userAuth.role, paperList)
    if (uInExamRes.data.length <= 0)
      return uInExamRes
    let uInExamPapers = uInExamRes.data
    // 查询用户未考过的试卷
    let uCanExamRes = await this.filterUserCanExamPapers(userAuth.uid, uInExamPapers)
    if (uCanExamRes.data.length <= 0)
      return uCanExamRes
    return {
      code: 0,
      data: uCanExamRes.data,
      message: '成功',
    }
  }

  // 获取正在考试中的试卷
  async getInExamPaper() {
    let cur_date = Date.now()
    const paperRes = await this.paperCt.where({
      status: 1,
      ['sel_time.0']: this.dbCmd.lt(cur_date),
      ['sel_time.1']: this.dbCmd.gt(cur_date)
    }).get()
    console.log("paperRes", paperRes)
    //查询到正在考试的试卷
    let paperList = paperRes.data
    console.log("paperList", paperList)
    return {
      code: 0,
      data: paperList,
      message: paperList.length <= 0 ? "没有考试中的试卷" : "success"
    }
  }

  // 筛选用户可考试的试卷
  async filterUserInExamPapers(userRoles, paperList) {
    let mPpList = [] //属于用户的试卷
    paperList.forEach(paperItem => {
      let hasIn = false //是否有相同元素
      paperItem.user_role.forEach(paperRole => {
        let inRole = userRoles.includes(paperRole)
        if (inRole) hasIn = true
      })
      //判断试卷的角色和用户的角色有相同元素，就将试卷导出到mPpList
      if (hasIn) mPpList.push(paperItem)
    })
    console.log("filterUserInExamPapers", mPpList)
    return {
      code: 0,
      data: mPpList,
      message: mPpList.length <= 0 ? "没有符合用户的试卷" : "success"
    }
  }

  // 筛选用户可考、未考的试卷
  async filterUserCanExamPapers(uid, paperList) {
    let uExamRes = await this.getUserExams("", uid)
    let uExamPapers = uExamRes.data //用户已经考过的试卷
    console.log("uExamPapers", uExamPapers)
    let mPpList = [] //用户未考的试卷
    paperList.forEach(paperItem => {
      let hasIn = false //是否有相同元素
      uExamPapers.forEach(uExamPaper => {
        if (paperItem._id == uExamPaper.paperId) hasIn = true
      })
      //判断试卷的id没有在用户考过的试卷中，就将试卷导出到mPpList
      if (!hasIn) mPpList.push(paperItem)
    })
    console.log("filterUserCanExamPapers", mPpList)
    return {
      code: 0,
      data: mPpList,
      message: mPpList.length <= 0 ? "没有用户待考试的试卷" : "success"
    }
  }

  // 获取试卷详情
  async getPaperInfo(paperId) {
    let paper_res = await this.paperCt.doc(paperId).get()
    let paper = paper_res.data[0]
    console.log("getPaperInfo", paper.type)
    if (paper.type === 1) {//随机选题
      let rdm_que_num = paper.rdm_que_num
      rdm_que_num = parseInt(rdm_que_num / 2)
      let ques_select = await this.questionCt.aggregate().match({type: 0}).sample({size: rdm_que_num}).end()
      let ques_decide = await this.questionCt.aggregate().match({type: 1}).sample({size: rdm_que_num}).end()
      paper.question_list = ques_select.data.concat(ques_decide.data)
    }
    paper.question_list.forEach(que => {
      que.title = que.title.replace(/\b\d+[、.．]/g, "")
      if (que.options) que.options.forEach(opt => opt.content = opt.content.replace(/^[、.．]/g, ""))
      que.single = que.answers && que.answers.length === 1
    })
    return {code: 0, data: paper, message: 'success'}
  }

  // 创建用户考试试卷
  async createExam({useTime, paperId, que_list, uniIdToken}) {
    let errMsg = "";
    let create_date = Date.now()
    if (!paperId) errMsg = "需要paperId参数";
    if (!uniIdToken) errMsg = "需要uniIdToken参数"
    if (!que_list) errMsg = "需要question_list参数";
    if (errMsg)
      return {
        code: 1,
        data: "",
        message: errMsg
      }
    // 添加用户userId标识
    await this.service.user.checkToken(uniIdToken)
    const userId = this.ctx.auth.uid
    console.log("userId", userId)
    let myExam = await this.examCt.where({userId}).get()
    console.log("myExam======", myExam)
    if (myExam.data && myExam.data.length > 0) return {code: 1, data: "", message: "已经考过了"}
    let {totalScore, uTotalScore, question_list} = await this.computePaperScore({paperId, que_list})
    let exam_obj = {paperId, useTime, question_list, userId, totalScore, uTotalScore, create_date}
    console.log("exam_obj", exam_obj)
    return this.examCt.add(exam_obj)
  }

  // 计算试卷分数
  async computePaperScore({paperId, que_list}) {
    let totalScore = 0 //试卷总分数
    let uTotalScore = 0 //用户得到总分数
    que_list.forEach(queItem => {
      // console.log("queItem", queItem)
      let isEqu = ""
      if (queItem.type == 0 && queItem.uAnswer) {
        if (typeof queItem.uAnswer == 'string') queItem.uAnswer = [queItem.uAnswer]
        isEqu = this.isArrayEquals(queItem.uAnswer, queItem.answers)
      }
      if (queItem.type == 1 && queItem.uDecide) {
        isEqu = queItem.uDecide.toString() === queItem.decide.toString()
      }
      queItem.uScore = isEqu ? queItem.score : 0; //这里给每道题进行分值计算
      uTotalScore += queItem.uScore
      totalScore += queItem.score
    })
    console.log("computePaperScore", totalScore, uTotalScore, que_list)
    return {totalScore, uTotalScore, question_list: que_list}
  }

  // 判断两个数组是否一致
  isArrayEquals(array1, array2) {
    console.log("isArrayEquals", array1, array2)
    return array1.length == array2.length && array1.every((v, i) => {
      return v === array2[i]
    });
  }

  // 用户已经考过的考试uniIdToken和uid两参数任选一个
  async getUserExams(uniIdToken, uid = "") {
    if (!uid) await this.service.user.checkToken(uniIdToken)
    uid = this.ctx.auth.uid
    let $ = this.db.command.aggregate
    let uExams = await this.examCt.aggregate().match({userId: uid})
        .lookup({from: "paper", localField: "paperId", foreignField: "_id", as: "paperList"})
        .replaceRoot({newRoot: $.mergeObjects([$.arrayElemAt(['$paperList', 0]), '$$ROOT'])})
        .project({paperList: 0}).end()
    console.log("getUserExams", uExams.data, uid)
    let result = {
      code: 0,
      data: uExams.data,
      message: uExams.data.length <= 0 ? '没有用户的考卷' : 'success'
    }
    return result;
  }

  async getExamInfo(examId) {
    let $ = this.db.command.aggregate
    let exam = await this.examCt.aggregate().match({_id: examId})
        .lookup({from: "paper", localField: "paperId", foreignField: "_id", as: "paperList"})
        .replaceRoot({newRoot: $.mergeObjects([$.arrayElemAt(['$paperList', 0]), '$$ROOT'])})
        .project({paperList: 0}).end()
    console.log("getExamInfo", exam)
    let result = {
      code: 0,
      data: exam.data,
      message: exam.data.length <= 0 ? '查询失败' : 'success'
    }
    return result;
  }

  async getExamSort(uniIdToken) {
    let examId = ''
    let paperId = ''
    let examObj = await this.getUserExams(uniIdToken)
    if (examObj.data.length > 0) paperId = examObj.data[0].paperId, examId = examObj.data[0]._id
    console.log("getExamSort-examId", paperId)
    let $ = this.db.command.aggregate
    let result = await this.db.collection('exam').aggregate()
        .lookup({from: "paper", localField: "paperId", foreignField: "_id", as: "paperList"})
        .lookup({from: 'uni-id-users', localField: 'userId', foreignField: '_id', as: 'userList'})
        .replaceRoot({newRoot: $.mergeObjects([$.arrayElemAt(['$paperList', 0]), '$$ROOT'])}) //直接将paperList里面的属性解析到外层
        .unwind('$userList')//将userList转换成对象
        .project({
          title: 1,
          username: "$userList.username",
          mobile: "$userList.mobile",
          paperType: "$type",
          useTime: 1,
          sel_time: 1,
          create_date: 1,
          totalScore: 1,
          uTotalScore: 1,
          question_list: 1
        })
        .sort({uTotalScore: -1, useTime: 1}).end()
    console.log("getExamSort", result)
    let index = 1
    if (result.data && result.data.length > 0)
      result.data.forEach(exam => {
        exam.index = index++
        exam.useTime = exam.useTime + "分钟"
        exam.myExam = exam._id === examId
      })
    return result
  }
}
